#include <iostream>
#include <list>
#include <map>
#include <string>
#include <fstream>
#include <boost/program_options.hpp>

#include "Config.h"
#include "TCPServer.h"
#include "Common.h"
#include "Objects.h"
#include "Global.h"
#include "DatabaseMysql.h"
using namespace RisingStar;
using namespace std;

using namespace  boost::program_options;

#include "WebSocketServer.h"





#include <string>   
#include <iostream>   
#include "boost/regex.hpp"   
 
int main1(int argc, char ** argv)   
{   
    if (argc != 4)   
    {      
        std::cerr<<"Usage: " << argv[0] <<" option regex text\n"   
                <<" option: 0 --whole match\n"   
                <<"        1 --sub match\n"   
                <<"        2 --replace match\n";   
        return 1;   
    }      
    
    boost::regex oRegex(argv[2]);   
    boost::smatch oResults;   
    std::string strStr(argv[3]);   
    std::string strRes;   
    
    switch (atoi(argv[1]))   
    {      
    case 0:   
        if(boost::regex_match(strStr, oResults, oRegex))   
        {      
            std::cout << strStr << " matches " << oRegex << "\n";   
			for (size_t i = 0; i < oResults.size(); ++i)
			{
				if (oResults[i].matched)
					std::cout << oResults[i] << std::endl;
			}
			
        }      
        else   
        {      
            std::cout << strStr << " doesn't match " << oRegex << "\n";   
        }      
        break;   
    case 1:   
        if(boost::regex_search(strStr, oResults, oRegex))   
        {   
            std::cout << strStr << " matches " << oRegex << "\n";   
			for (size_t i = 0; i < oResults.size(); ++i)
			{
				if (oResults[i].matched)
					std::cout << oResults[i] << std::endl;
			}
        }   
        else   
        {   
            std::cout << strStr << " doesn't match " << oRegex << "\n";   
        }   
        break;   
    case 2:   
        strRes = boost::regex_replace(strStr, oRegex, "");   
        std::cout << "strRes=" << strRes << "\n";   
        break;   
    default:   
        std::cerr << "Invalid option: " << argv[1] << "\n";   
        break;   
    }   
} 


bool DoCmdLine(int argc,char** argv,variables_map& vm)
{
	boost::program_options::options_description opts("腾星车位管理系统应用服务端程序 选项");
	opts.add_options()
	("help,h","帮助")
	("Print,P","打印变量信息")
	("exportsql,e",boost::program_options::value<string>(),"输出Mysql文件")
	("databaseName,n",boost::program_options::value<string>(),"指定生成数据库的名称")	
	("dicFile,d",boost::program_options::value<string>(),"指定字典表文件")
	("cmdFile,c",boost::program_options::value<string>(),"指定测试json报文命令")
	("databaseDir,D",boost::program_options::value<string>(),"指定数据库加载的目录")
	("createAllDatabase,A",boost::program_options::value<string>(),"导出所有的可用数据库到指定目录")
	("NotRun,N","仅调试，不运行")

	("path,p",boost::program_options::value<string>(),"配置方案目录");

	//variables_map vm;
	try
	{
		store(parse_command_line(argc,argv,opts),vm); // 分析参数
	}
	catch(boost::program_options::error_with_no_option_name &ex)
	{
		cout<<ex.what()<<endl;
	}

	notify(vm); // 将解析的结果存储到外部变量
	if (vm.count("help"))
	{
		cout<<opts<<endl;
		return false;
	}	

	if (vm.count("Print"))
	{
		sGlobal.Print();
		return false;
	}
	if (vm.count("NotRun"))
	{
		return false;
	}
	
	return true;
}

int main(int argc,char** argv)
{	
	try 
	{

		variables_map vm;
		
		if(!DoCmdLine(argc,argv,vm))
		{
			return -1;
		}

		//设定配置目录
		if(vm.count("path"))
		{
			string path = vm["path"].as<string>();
			cout<<"设定配置目录："<<path<<endl;
			sGlobal.Values["配置方案目录"] = vm["path"].as<string>();
		}
		//创建可用对象
		sGlobal.CreateObjects();	
		

		
		if(vm.count("databaseDir"))
		{
			string databaseDir = vm["databaseDir"].as<string>();
			sGlobal.GetDatabaseCfg(databaseDir);
		}
	
		//设定字典表文件
		if(vm.count("dicFile"))
		{
			string dicFile = vm["dicFile"].as<string>();
			sGlobal.Values["字典表"] = dicFile;
		}
		
		
		//导入字典表
		sGlobal.ImportDic(sGlobal.Values["字典表"]);
		
		//导出Mysql配置文件
		if(vm.count("databaseName"))
		{
			sGlobal.Values["数据库名"] = vm["databaseName"].as<string>();
		}
		else
		{
			sGlobal.Values["数据库名"] = "ParkingSpaceData";
		}

		//导出数据库文件需要依赖于字典表文件的参数配置，因而只能放到导入字典表之后
		//导出Mysql配置文件
		if(vm.count("exportsql"))
		{
			string sqlFile = vm["exportsql"].as<string>();
			sGlobal.CreateMySQLFile(sqlFile,sGlobal.Values["数据库名"]);
			cout<<"已经导出Mysql配置文件到:"<<sqlFile<<endl;
			return -1;
		}
		if(vm.count("createAllDatabase"))
		{
			string sqlDir = vm["createAllDatabase"].as<string>();
			map<string,TDatabaseParam >::iterator lIter;
			string outFileName = sqlDir + "/run.sh";
			std::ofstream output(outFileName.c_str(),ios::out);
			if(output.good())
			{
				for(lIter = sGlobal.RemoteDatabaseArr.begin();lIter != sGlobal.RemoteDatabaseArr.end();++lIter)
				{
					string databaseName = lIter->first;
					string dbFileName = databaseName + ".sql";
					string sqlFile = sqlDir + "/";
					sqlFile += dbFileName;

					if(sGlobal.CreateMySQLFile(sqlFile,databaseName,&lIter->second))
					{
						output<<"mysql";
								if(lIter->second.property["地址"] != "")
								{
									output<<" -h "
									<<lIter->second.property["地址"];
								}
								if(lIter->second.property["端口"] != "")
								{
									output<<" -P "
									<<lIter->second.property["端口"];
								}
								output<<" -u "
								<<lIter->second.property["用户名"]
								<<" -p"
								<<lIter->second.property["密码"]
								<<" <"
								<<dbFileName
								<<endl;
					}
				}
				output.close();
			}
			return -1;
		}
	/*	CDatabaseMysql mysql;
		if(mysql.Connect("root","123456","ParkingSpaceData","127.0.0.1"))
		{
			list<map<string,string> > data;
			
			if(mysql.SearchList("select * from TUserData",data))
			{
				list<map<string,string> >::iterator lIter;
				for(lIter = data.begin();lIter != data.end();++lIter)
				{
					map<string,string>::iterator dlIter;
					if(lIter == data.begin())
					{
						cout<<endl;
						for(dlIter = (*lIter).begin();dlIter != (*lIter).end();++dlIter)
						{
							cout<<dlIter->first<<"\t";
						}
						cout<<endl;
					}
					for(dlIter = (*lIter).begin();dlIter != (*lIter).end();++dlIter)
					{
						cout<<dlIter->second<<"\t";
					}
					cout<<endl;
				}
				
			}
			else
			{
				cout<<"执行数据库查询时发生失败"<<endl;
			}
			mysql.Close();
		}
		else
		{
			cout<<"无法连接数据库"<<endl;
		}
		*/
		
		//解析命令文件，用于测试
		if(vm.count("cmdFile"))
		{
			string cmdFile = vm["cmdFile"].as<string>();
			std::ifstream t(cmdFile.c_str(),ios::in);  
			if(t.good())
			{
				string str((istreambuf_iterator<char>(t)),  
				istreambuf_iterator<char>());
				
				CObjects objs(str);
				cout<<objs.Out()<<endl;
			}
			else
			{
				cout<<RSTR("错误:")<<"无法打开指定的文件:"<<cmdFile<<endl;
			}
			return -1;
		}
		//设定并打开webScoket服务
		CWebSocketServer server(8080);
		server.Run();
			
		
			
	/*	cout<<objs.Out()<<endl;
		_EVENT("程序开始运行");
		

	
		CTCPServer* pService = new CTCPServer(6688);
		_EVENT("服务开始运行");
	//	pService->run();
		pService->Run();




		_WARNNING("服务已经全部结束运行了");

		delete pService;*/

		_ERROR("类已经被删除了");

		_WARNNING("程序已经退出");
		
	} 
 
	catch (boost::exception &e) 
	{ 

		TRACE("%s\n",boost::diagnostic_information(e).c_str());//boost::diagnostic_information 会提取所有信息
 
	} 
	catch(std::exception& e){//catch的前后顺序定义会有区别抓取的

		TRACE("%s\n",e.what());	
	}


	
	return 0;
}/**/


